#include "hplczkyspumpprotocol.h"
#include "hplczkyspumpparsepacket.h"
#include "hplczkyspumpsendpacket.h"
#include "hplczkyspumpprotocoldata.h"
#include "hplczkyspumpsendsystempacket.h"
#include "hplczkyspumpparsesystempacket.h"
#include "common/hplczkysmakepacket.h"

#include "modulehplccmdid.h"
#include <QVariant>

namespace hplc
{
namespace zkys
{

HplcZkysPumpProtocol::HplcZkysPumpProtocol(PumpParam &param, QObject *parent)
    : HplcZkysPumpProtocol (*new HplcZkysPumpProtocolData(), param, parent)
{

}

HplcZkysPumpProtocol::HplcZkysPumpProtocol(HplcZkysPumpProtocolData &data, PumpParam &param, QObject *parent)
    : HplcZkysProtocolCommon (data, param, parent)
    , m_param(&param)
{
    HplcZkysPumpParsePacket *parser = new HplcZkysPumpParsePacket(data, param, this);
    connect(parser, &BaseParsePacket::parseCompleted, this, &BaseProtocol::parseCompleted);
    HplcZkysPumpSendPacket *sender = new HplcZkysPumpSendPacket (data, this);
    connect(sender, &HplcZkysSendCommonPacket::requestSend, this, &HplcZkysProtocolCommon::requestSend);

    HplcZkysPumpSendSystemPacket *systemSender = new HplcZkysPumpSendSystemPacket(data);
    HplcZkysPumpParseSystemPacket *systemParser = new HplcZkysPumpParseSystemPacket(data, param);
    connect(systemParser, &HplcZkysPumpParseSystemPacket::parseCompleted, this, &BaseProtocol::parseCompleted);

    data.m_parser = parser;
    data.m_sender = sender;
    data.m_systemParser = systemParser;
    data.m_systemSender = systemSender;
}

HplcZkysPumpProtocol::~HplcZkysPumpProtocol()
{
    HplcZkysPumpProtocolData *d = static_cast<HplcZkysPumpProtocolData*>(m_d);
    delete d->m_sender;
    delete d->m_parser;
    delete d->m_systemParser;
    delete d->m_systemSender;
}

bool HplcZkysPumpProtocol::setProtocolCmd(int id, QVariant &var)
{
    switch (id)
    {
        // pump
        case hplc::PumpCmdID_SetFlow:
            getPumpSender()->setFlow(var.toFloat());
        break;
        case hplc::PumpCmdID_SetFlowPercent:
            getPumpSender()->setFlowPercent(var.toUInt());
        break;
        case hplc::PumpCmdID_SetPressureMin:
            getPumpSender()->setPressMin(var.toFloat());
        break;
        case hplc::PumpCmdID_SetPressureMax:
            getPumpSender()->setPressMax(var.toFloat());
        break;
        case hplc::PumpCmdID_SetPressureWarning:
            getPumpSender()->setPressWarning(var.toFloat());
        break;
        case hplc::PumpCmdID_SetStartStop:
            getPumpSender()->setStartStop(var.toUInt());
        break;
        case hplc::PumpCmdID_SetPauseRestore:
            getPumpSender()->setPauseRestore(var.toUInt());
        break;
        case hplc::PumpCmdID_SetPurge:
            getPumpSender()->setPurge(var.toUInt());
        break;
        case hplc::PumpCmdID_SetPurgeFlow:
            getPumpSender()->setPurgeFlow(var.toFloat());
        break;
        case hplc::PumpCmdID_SetPurgeTime:
            getPumpSender()->setPurgeTime(var.toUInt());
        break;
        case hplc::PumpCmdID_SetPressZero:
            getPumpSender()->setPressZero();
        break;
        case hplc::PumpCmdID_SetPressUploadFreq:
            getPumpSender()->setPressUploadFreq(var.toUInt());
        break;
        case hplc::PumpCmdID_SetFlowPressCompen:
            getPumpSender()->setPressCompen(var.toUInt());
        break;
        case hplc::PumpCmdID_SetMode:
            getPumpSender()->setMode(var.toUInt());
        break;
        case hplc::PumpCmdID_SetPressure:
            getPumpSender()->setPress(var.toFloat());
        break;
        case hplc::PumpCmdID_SetRunMode:
            getPumpSender()->setRunMode(var.toUInt());
        break;

        case hplc::PumpCmdID_Set_CP_FlowMax:
            getPumpSender()->CP_SetFlowMax(var.toFloat());
        break;
        case hplc::PumpCmdID_Set_CP_FlowMin:
            getPumpSender()->CP_SetFlowMin(var.toFloat());
        break;
        case hplc::PumpCmdID_Set_CP_PressThreshold:
            getPumpSender()->CP_SetPressThreshold(var.toFloat());
        break;
        case hplc::PumpCmdID_Set_CP_Press:
            getPumpSender()->CP_SetPressSet(var.toFloat());
        break;
        case hplc::PumpCmdID_Set_CP_PID:
            {
            hplc::PID pid = var.value<hplc::PID>();
            getPumpSender()->CP_SetPID(pid.p, pid.i, pid.d);
            }
        break;
        case hplc::PumpCmdID_Set_CP_PressPidOutUploadFreq:
            getPumpSender()->CP_SetPressPIDOutUploadFreq(var.toUInt());
        break;

        // pump system
        case hplc::PumpSystemCmdID_SetWorkModePressureCalib:
            getPumpSystemSender()->setWorkMode(hplc::PumpWorkMode_PressureCalib, var.toUInt());
        break;
        case hplc::PumpSystemCmdID_SetWorkModeRateCalib:
            getPumpSystemSender()->setWorkMode(hplc::PumpWorkMode_RateCalib, var.toUInt());
        break;
        case hplc::PumpSystemCmdID_SetWorkModePulseCompenCalib:
            getPumpSystemSender()->setWorkMode(hplc::PumpWorkMode_PulseCompenCalib, var.toUInt());
        break;
        case hplc::PumpSystemCmdID_SetWorkModeMotorCurrentCalib:
            getPumpSystemSender()->setWorkMode(hplc::PumpWorkMode_MotorCurrentCalib, var.toUInt());
        break;
        case hplc::PumpSystemCmdID_SetFlowCalibData:
            {
            getPumpSystemSender()->setFlowCalibDataCMD(1);
            QList<hplc::PumpRateCalibData> list;
            list = var.value<QList<hplc::PumpRateCalibData>>();
            foreach (auto var, list)
            {
                getPumpSystemSender()->setFlowCalibData(var.rpm, var.rate);
            }
            getPumpSystemSender()->setFlowCalibDataCMD(0);
            }
        break;
        case hplc::PumpSystemCmdID_SetFlowCalibLoadParam:
            {
            hplc::PumpLoadCalibParam param = var.value<hplc::PumpLoadCalibParam>();
            getPumpSystemSender()->setFlowCalibLoadParam(param.rate, param.realRate, param.pressure);
            }
        break;
        case hplc::PumpSystemCmdID_SetPressCalibData:
            {
            getPumpSystemSender()->setPressCalibDataCMD(1);
            QList<hplc::PumpPressureCalibData> list;
            list = var.value<QList<hplc::PumpPressureCalibData>>();
            foreach (auto var, list)
            {
                getPumpSystemSender()->setPressCalibData(var.adc, var.pressure);
            }
            getPumpSystemSender()->setPressCalibDataCMD(0);
            }
        break;
        case hplc::PumpSystemCmdID_SetPulseCompenCalibDataCmd:
            getPumpSystemSender()->setPulseCompenDataCMD(var.toUInt());
        break;
        case hplc::PumpSystemCmdID_SetPulseCompenCalibData:
            {
            getPumpSystemSender()->setPulseCompenDataCMD(1);
            QList<hplc::PumpPulseCompenCalibData> list;
            list = var.value<QList<hplc::PumpPulseCompenCalibData>>();
            foreach (auto var, list)
            {
                getPumpSystemSender()->setPulseCompenData(var.position, var.factor);
            }
            getPumpSystemSender()->setPulseCompenDataCMD(0);
            }
        break;
        case hplc::PumpSystemCmdID_SetPulseCompenDebugCmd:
            getPumpSystemSender()->setPulseCompenDebugCMD(var.toUInt());
        break;
        case hplc::PumpSystemCmdID_SetStepMotorIRun:
            getPumpSystemSender()->setStepMotorCurrentRun(var.toUInt());
        break;
        case hplc::PumpSystemCmdID_SetMotorCurrentCalibData:
            {
            getPumpSystemSender()->setMotorCurrentDataCMD(1);
            QList<hplc::PumpStepMotorCurrentCalibData> list;
            list = var.value<QList<hplc::PumpStepMotorCurrentCalibData>>();
            foreach (auto var, list)
            {
                getPumpSystemSender()->setMotorCurrentData(var.rpm, var.current);
            }
            getPumpSystemSender()->setMotorCurrentDataCMD(0);
            }
        break;
        case hplc::PumpSystemCmdID_SetPumpMaterial:
            getPumpSystemSender()->setPumpMaterial(var.toUInt());
        break;
        case hplc::PumpSystemCmdID_SetCurrentRpm:
        break;

        default:
            return HplcZkysProtocolCommon::setProtocolCmd(id, var);
        break;
    }
    return true;
}

bool HplcZkysPumpProtocol::getProtocolCmd(int id, QVariant &var)
{
    switch (id)
    {
        // pump
        case hplc::PumpCmdID_GetFlow:
            getPumpSender()->getFlow();
        break;
        case hplc::PumpCmdID_GetFlowPercent:
            getPumpSender()->getFlowPercent();
        break;
        case hplc::PumpCmdID_GetPressureMin:
            getPumpSender()->getPressMin();
        break;
        case hplc::PumpCmdID_GetPressureMax:
            getPumpSender()->getPressMax();
        break;
        case hplc::PumpCmdID_GetPressureWarning:
            getPumpSender()->getPressWarning();
        break;
        case hplc::PumpCmdID_GetStartStop:
            getPumpSender()->getStartStop();
        break;
        case hplc::PumpCmdID_GetPauseRestore:
            getPumpSender()->getPauseRestore();
        break;
        case hplc::PumpCmdID_GetPurge:
            getPumpSender()->getPurge();
        break;
        case hplc::PumpCmdID_GetPurgeFlow:
            getPumpSender()->getPurgeFlow();
        break;
        case hplc::PumpCmdID_GetPurgeTime:
            getPumpSender()->getPurgeTime();
        break;
        case hplc::PumpCmdID_GetPressZero:
            getPumpSender()->getPressZeroVoltage();
        break;
        case hplc::PumpCmdID_GetPressUploadFreq:
            getPumpSender()->getPressUploadFreq();
        break;
        case hplc::PumpCmdID_GetFlowPressCompen:
            getPumpSender()->getPressCompen();
        break;
        case hplc::PumpCmdID_GetMode:
            getPumpSender()->getMode();
        break;
        case hplc::PumpCmdID_GetPressure:
            getPumpSender()->getPress();
        break;
        case hplc::PumpCmdID_GetRunMode:
            getPumpSender()->getRunMode();
        break;

        case hplc::PumpCmdID_Get_CP_FlowMax:
            getPumpSender()->CP_GetFlowMax();
        break;
        case hplc::PumpCmdID_Get_CP_FlowMin:
            getPumpSender()->CP_GetFlowMin();
        break;
        case hplc::PumpCmdID_Get_CP_PressThreshold:
            getPumpSender()->CP_GetPressThreshold();
        break;
        case hplc::PumpCmdID_Get_CP_Press:
            getPumpSender()->CP_GetPressSet();
        break;
        case hplc::PumpCmdID_Get_CP_PID:
            getPumpSender()->CP_GetPID();
        break;
        case hplc::PumpCmdID_Get_CP_PressPidOut:
            getPumpSender()->CP_GetPressPIDOut();
        break;
        case hplc::PumpCmdID_Get_CP_PressPidOutUploadFreq:
            getPumpSender()->CP_GetPressPIDOutUploadFreq();
        break;

        // pump system
        case hplc::PumpSystemCmdID_GetWorkMode:
            getPumpSystemSender()->getWorkMode();
        break;
        case hplc::PumpSystemCmdID_GetFlowCalibData:
            getPumpSystemSender()->getFlowCalibData();
        break;
        case hplc::PumpSystemCmdID_GetFlowCalibLoadParam:
            getPumpSystemSender()->getFlowCalibLoadParam();
        break;
        case hplc::PumpSystemCmdID_GetPressCalibData:
            getPumpSystemSender()->getPressCalibData();
        break;
        case hplc::PumpSystemCmdID_GetPulseCompenCalibData:
            getPumpSystemSender()->getPulseCompenData();
        break;
        case hplc::PumpSystemCmdID_GetStepMotorIRun:
            getPumpSystemSender()->getStepMotorCurrentRun();
        break;
        case hplc::PumpSystemCmdID_GetMotorCurrentCalibData:
            getPumpSystemSender()->getMotorCurrentData();
        break;
        case hplc::PumpSystemCmdID_GetPumpMaterial:
            getPumpSystemSender()->getPumpMaterial();
        break;
        case hplc::PumpSystemCmdID_GetCurrentRpm:
            getPumpSystemSender()->getCurrentRpm();
        break;

        default:
            return HplcZkysProtocolCommon::getProtocolCmd(id, var);
        break;
    }
    return true;
}

HplcZkysPumpParsePacket *HplcZkysPumpProtocol::getPumpParser()
{
    return static_cast<HplcZkysPumpParsePacket*>(m_d->m_parser);
}

HplcZkysPumpParseSystemPacket *HplcZkysPumpProtocol::getPumpSystemParser()
{
    HplcZkysPumpProtocolData *m_d = static_cast<HplcZkysPumpProtocolData*>(this->m_d);
    return m_d->m_systemParser;
}

HplcZkysPumpSendPacket *HplcZkysPumpProtocol::getPumpSender()
{
    return static_cast<HplcZkysPumpSendPacket*>(m_d->m_sender);
}

HplcZkysPumpSendSystemPacket *HplcZkysPumpProtocol::getPumpSystemSender()
{
    HplcZkysPumpProtocolData *m_d = static_cast<HplcZkysPumpProtocolData*>(this->m_d);
    return m_d->m_systemSender;
}

HplcZkysSendCommonPacket *HplcZkysPumpProtocol::getCommonSender()
{
    return static_cast<HplcZkysSendCommonPacket*>(m_d->m_sender);
}

HplcZkysSendCommonSystemPacket *HplcZkysPumpProtocol::getCommonSystemSender()
{
    HplcZkysProtocolCommonData *m_d = static_cast<HplcZkysProtocolCommonData*>(this->m_d);
    return m_d->m_commonSystemSender;
}

void HplcZkysPumpProtocol::setModel(quint8 model)
{
    m_param->deviceParam.model = static_cast<hplc::PumpModel>(model);

    QVariant var;
    var.setValue(m_param->deviceParam.model);
    emit parseCompleted(hplc::CommonSystemCmdID_SetModel, var);
}

} // zkys
} // hplc

